#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    file = new QFile(QCoreApplication::applicationDirPath() + "/logs.txt");
    file->open(QIODevice::WriteOnly | QIODevice::Text);

    QPen red(Qt::cyan);
    red.setWidth(2);
    series1 = new QSplineSeries();
    series2 = new QSplineSeries();
    series1->setPen(red);
    QPen yellow(Qt::yellow);
    yellow.setWidth(2);
    series2->setPen(yellow);

//    timer = new QTimer(this);                                        //创建定时器
//    connect(timer, SIGNAL(timeout()), this, SLOT(addpiont()));      //连接定时器与定时溢出处理槽函数
//    timer->start(1000);

    ledOff = new QTimer(this);                                        //创建定时器
    connect(ledOff, SIGNAL(timeout()), this, SLOT(setLedOff()));

    QBrush b;
    b.setColor("white");

    chart = new QChart();
    chart->addSeries(series1);
    chart->addSeries(series2);
    chart->legend()->hide();
    chart->setTitleFont(QFont("", 14));
    chart->setTitle("吸力曲线");
    chart->setTitleBrush(b);

    axisX = new QDateTimeAxis();
    axisX->setTickCount(10);
    axisX->setFormat("hh:mm:ss");
    axisX->setTitleText("时间");
    axisX->setTitleBrush(b);
    axisX->setLabelsColor("white");
    chart->addAxis(axisX, Qt::AlignBottom);
    series1->attachAxis(axisX);
    series2->attachAxis(axisX);

    axisY = new QtCharts::QValueAxis();
    axisY->setLabelFormat("%i");
    axisY->setTitleText("吸力 Pa");
    axisY->setTitleBrush(b);
    axisY->setLabelsColor("white");
    axisX->setGridLineVisible(false);                    //设置Y轴网格不显示
    chart->addAxis(axisY, Qt::AlignLeft);
    series1->attachAxis(axisY);
    series2->attachAxis(axisY);

    //把chart显示到窗口上
    ui->widget->setChart(chart);
    ui->widget->setRenderHint(QPainter::Antialiasing);   //设置抗锯齿
    chart->setBackgroundVisible(false); // 背景透明

    d = new Dialog(this);

    serialPort = new QSerialPort(this);
    connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::readRequest);

    // 状态栏：时钟
    ClockStatic = new QLabel("", this);
    ClockStatic->setMinimumWidth(150);
    ClockStatic->setAlignment(Qt::AlignCenter);  //水平居中(HCenter)。
    ClockStatic->setStyleSheet("color:rgb(255, 255, 255);");
    statusBar()->addPermanentWidget(ClockStatic); //现实永久信息
    clocktime = new QTimer(this);
    connect(clocktime, &QTimer::timeout,[this]() {
        QDateTime t = QDateTime::currentDateTime();
        ClockStatic->setText(t.toString("yyyy-MM-dd hh:mm:ss"));
    });
    clocktime->start(1000);

    LedStatic = new QLabel("<font>&#9679;</font>", this);
    LedStatic->setStyleSheet("color:rgb(190,190,190);");
    statusBar()->addPermanentWidget(LedStatic);

    ComStatic = new QLabel("通讯端口状态", this);
    ComStatic->setMinimumWidth(200);
    ComStatic->setAlignment(Qt::AlignCenter);  //水平居中(HCenter)。
    ComStatic->setStyleSheet("color: rgb(255, 255, 255);");
    statusBar()->addPermanentWidget(ComStatic); //现实永久信息
    statusBar()->setStyleSheet("color: rgb(255, 255, 255);");
    statusBar()->showMessage(this->windowTitle());

    QLabel *Copyright = new QLabel("<font>Copyright&#169; 2019</font> 武汉中祺科技", this);
    Copyright->setMinimumWidth(250);
    Copyright->setAlignment(Qt::AlignCenter);  //水平居中(HCenter)。
    Copyright->setStyleSheet("color: rgb(255, 255, 255);");
    statusBar()->addPermanentWidget(Copyright); //现实永久信息

    this->showFullScreen();  // 全屏显示
    setCom();
}

void MainWindow::setLedOff()
{
    LedStatic->setStyleSheet("color:rgb(190,190,190);");
    ledOff->stop();
}

void MainWindow::setLedOn()
{
    ledOff->start(100);
    LedStatic->setStyleSheet("color:rgb(0,255,0);");
}

void MainWindow::setCom()
{
    if (serialPort->isOpen()) serialPort->close();
    QSettings ini(QCoreApplication::applicationDirPath() + "/config.ini", QSettings::IniFormat);
    mm = ini.value("sys/axisY", 2).toInt();
    QString portName = ini.value("sys/com", "ttyS0").toString();
    serialPort->setPortName(portName);
    serialPort->setBaudRate(QSerialPort::Baud38400);
    serialPort->setParity(QSerialPort::NoParity);
    serialPort->setDataBits(QSerialPort::Data8);
    serialPort->setStopBits(QSerialPort::OneStop);
    serialPort->setFlowControl(QSerialPort::NoFlowControl);
    serialPort->setReadBufferSize(1024);

    if (serialPort->open(QIODevice::ReadWrite)) {
        ComStatic->setText(tr("通讯端口已连接：") + portName);
    } else {
        QMessageBox::critical(this, tr("打开失败"), tr("<font size='11' color='white'>通讯端口 ") + portName + tr(" 不存在或被占用.</font>"), QMessageBox::Ok);
    }
}

void MainWindow::changeComName(QString comname, int value)
{
    if (serialPort->portName() != comname or mm != value)
        setCom();
}

void MainWindow::readRequest()
{
    static QByteArray buf;
    int buflength, pox;

    setLedOn();

    buf += serialPort->readAll();

    pox = buf.indexOf(0xff); // 寻找开始标志 0xff
    if(pox>0)
        buf.remove(0, pox);  // 删除开始标志位前面无效数据

    buflength = buf.length();
    if (buflength < sizeof(double) * 12+3) {
        return;
    } else {
        logs(buf);
        memcpy(&bufdouble.b[0], buf.data(), sizeof(double) * 12+3);
        quint16 crc = CRC16((unsigned char *)bufdouble.b,97);
        if(crc == bufdouble.crc16)
        {   for (int i = 1; i <= 12; i++) {
                QLabel *lb = this->findChild<QLabel *>("num_" + QString::number(i));
                if (lb && (bufdouble.n[i - 1] < 5000) && (bufdouble.n[i - 1] > -100)) {
                    if (i == 2 or i == 5 or i == 8 or i == 11)
                        lb->setText(QString::number(bufdouble.n[i - 1], 'f', 1)+" A"); // 电流
                    else if (i == 3 or i == 9) {
                        if(bufdouble.n[i - 1]>0)
                            lb->setText("-" + QString::number(bufdouble.n[i - 1], 'f', 0)); // 吸力
                        else
                            lb->setText(QString::number(bufdouble.n[i - 1], 'f', 0)); // 吸力
                    }
                    else
                        lb->setText(QString::number(bufdouble.n[i - 1], 'f', 0));  // 转速
                }
            }
            drawLine(bufdouble.n[2], bufdouble.n[8]); // 画曲线
        }
        buf.clear();
    }
}

void MainWindow::drawLine(int i1, int i2)
{
    int tempint, yMin = 0, yMax = -3000;
    QDateTime currentTime = QDateTime::currentDateTime();
    //设置坐标轴显示范围
    axisX->setMin(currentTime.addSecs(-60 * mm));       //系统当前时间的前一秒
    axisX->setMax(currentTime.addSecs(0));            //系统当前时间

    if (series1->count() > 60 * mm) {
        series1->remove(0);
        series2->remove(0);

    }
    //增加新的点到曲线末端
    series1->append(currentTime.toMSecsSinceEpoch(), -i1);
    series2->append(currentTime.toMSecsSinceEpoch(), -i2);

    for (int i = 0; i < series1->count(); i++) {
        tempint = series1->points().at(i).y();
        yMin = yMin > tempint ? tempint : yMin;
        yMax = yMax < tempint ? tempint : yMax;
        tempint = series2->points().at(i).y();
        yMin = yMin > tempint ? tempint : yMin;
        yMax = yMax < tempint ? tempint : yMax;
    }
    axisY->setMin(yMin - 50);           //设置Y轴范围
    axisY->setMax(yMax + 50);

    //qDebug() << yMin << yMax << series1->count() << mm;

}

MainWindow::~MainWindow()
{
    /*delete chartView;
    delete axisX;
    delete axisY;
    delete chart;
    delete series1;
    delete series2;*/
    file->close();
    delete  serialPort;
    delete d;
    delete ui;

}

void MainWindow::on_pushButton_clicked()
{
    d->setModal(true);
    QObject::connect(d, SIGNAL(changeComed(QString, int)), this, SLOT(changeComName(QString, int)));
    d->show();
}

void MainWindow::on_pushButton_2_clicked()
{
    if (QMessageBox::question(this, "提示", "<font size='14' color='white'>确定关闭系统吗？</font>") == QMessageBox::Yes)
        system("shutdown -s -t 00");
}

void MainWindow::addpiont()
{
    int i1, i2;
    i1 = QRandomGenerator::global()->bounded(2000, 3000);
    i2 = QRandomGenerator::global()->bounded(2000, 3000);
    qDebug() << i1 << i2 << QString::number(123.4561, 'f', 0);
    drawLine(i1, i2);
}

quint16 MainWindow::CRC16(unsigned char *buf, int len)
{
    quint16 crc = 0xFFFF, UseHL;
    for (int pos = 0; pos < len; pos++)
    {
        crc ^= 0xff & buf[pos]; // XOR byte into least sig. byte of crc
        for (int i = 0; i <= 7; i++)   // Loop over each bit
        {
            UseHL = crc;
            crc >>= 1;

            if ((UseHL & 0x1) == 0x1)   // If the LSB is set
                crc ^= 0xA001;
        }
    }

    //高低字节转换
    //crc = ((crc & 0x00ff) << 8) | ((crc & 0xff00) >> 8);
    return crc;
}

void MainWindow::logs(QByteArray buf)
{
    QString s = "(" + QString::number(buf.length()) + "):" + buf.toHex() + "\n";
    file->write(s.toUtf8());
}
